package viper.badRelays;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.WindowConstants;

import viper.badRelays.BadRelaysLoggedOutPanel;
import viper.main.StateManager;

/**
 * @author Kevin Sin
 * 
 * Revision number: 1
 * Date created: 1/17/10
 * Date of Last Back-up on SVN: none
 * 
 * <p>This class is responsible for the GUI.  It interacts w/ StateManger only
 * to display the right info to the user and responds to user actions.  A CardLayout
 * is used to develop different panels and integrate them easily.
 */
public class ViperBadRelaysGUI extends JFrame{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	//Singleton structure.
	public final static ViperBadRelaysGUI INSTANCE = new ViperBadRelaysGUI();

	public static final String LOGGED_OUT_CARD = "LOGGED_OUT_CARD";
	public static final String RELAYS_CARD = "RELAYS_CARD";
	
	private JPanel cardPanel;
	private CardLayout cl;
	
	private RelaysPanel relaysPanel;
	private BadRelaysLoggedOutPanel badRelaysLoggedOutPanel;
	
	private JInternalFrame internalFrame;
	private JPanel framePanel;
	
	private JLabel label = new JLabel();
	private JLabel label2 = new JLabel();

	public JInternalFrame getInternalFrame() {
		return internalFrame;
	}
	
	public JPanel getFramePanel() {
		return framePanel;
	}

	private ViperBadRelaysGUI() {

		setTitle("VIPER Bad Relays");

		cardPanel = new JPanel();

		cl = new CardLayout();
		cardPanel.setLayout(cl);

		relaysPanel = new RelaysPanel();
		badRelaysLoggedOutPanel = new BadRelaysLoggedOutPanel();
		internalFrame = new JInternalFrame("title", false, false, false);
		
		internalFrame.setMinimumSize(new Dimension(500, 250));
		
		framePanel = new JPanel();
		internalFrame.add(framePanel);
		
		
		cardPanel.add(relaysPanel, RELAYS_CARD);
		cardPanel.add(badRelaysLoggedOutPanel, LOGGED_OUT_CARD);

		getContentPane().add(cardPanel, BorderLayout.NORTH);
		
		getContentPane().add(internalFrame);
	}

	/**
	 * Sets the size and displays the window.
	 */
	public void initialize(){
		setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setSize(500, 550);
		setResizable(false);
		changeCard(LOGGED_OUT_CARD);
		//changeCard(RELAYS_CARD);
		setVisible(true);
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				StateManager.INSTANCE.exit();
			}			
		});	 
	}
	
	/**
	 * @param cardName - which JPanel to display
	 * Changes the window title and updates each panel before showing that panel.
	 */
	public void changeCard(String cardName){
		//StateManager.INSTANCE.updatePeers();
		if(cardName.equals(LOGGED_OUT_CARD))
		{
			setTitle("VIPER Bad Relays - Logged Out");
		}
		else if(cardName.equals(RELAYS_CARD))
		{
			//StateManager.INSTANCE.updatePeers();
			setTitle("VIPER Bad Relays - logged in as " + BadRelaysStateManager.INSTANCE.getUsername());
			setUpInternalFrame();
			//loggedInPanel.update();
		}	
		cl.show(cardPanel, cardName);
	}
	
	public void setUpInternalFrame()
	{
		internalFrame.setTitle("Statistics");
		framePanel.removeAll();
		label.setText("  Dropped Packets: 0");
		label2.setText("  Delayed Packets: 0");
		
		GridLayout gridlayout = new GridLayout(2, 1);
		
		framePanel.setLayout(gridlayout);
		
		framePanel.add(label);
		framePanel.add(label2);
		
		internalFrame.setVisible(true);
	}
	
	/**
	 * For updating internal frame, which shows count of packets dropped and packets delayed.
	 */
	public void updateRelaysInternalFrame(int droppedPacketCount, int delayedPacketCount)
	{
		label.setText("  Dropped Packets: " + droppedPacketCount);
		label2.setText("  Delayed Packets: " + delayedPacketCount);
		label.repaint();
		label2.repaint();
	}
	
	public void changeInternalFrameRelays()
	{
		internalFrame.setTitle("Statistics");
		framePanel.removeAll();
		JButton button = new JButton("Cancel");
		final String calleeIP = (String)(StateManager.INSTANCE.getCalleeArray()[0]);
		String calleeName = (String)StateManager.INSTANCE.getCalleeArray()[1];
		button.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				StateManager.INSTANCE.cancelCall(calleeIP);
			}
        });
		framePanel.add(button);
		framePanel.add(new JLabel("Dialing " + calleeName + " (" + calleeIP + ")"));
		internalFrame.setVisible(true);
	}
	
	/**
	 * For displaying internal frame when transitioning to DIALING
	 */
	public void changeInternalFrameDialing()
	{
		internalFrame.setTitle("Dialing");
		framePanel.removeAll();
		JButton button = new JButton("Cancel");
		final String calleeIP = (String)(StateManager.INSTANCE.getCalleeArray()[0]);
		String calleeName = (String)StateManager.INSTANCE.getCalleeArray()[1];
		button.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				StateManager.INSTANCE.cancelCall(calleeIP);
			}
        });
		framePanel.add(button);
		framePanel.add(new JLabel("Dialing " + calleeName + " (" + calleeIP + ")"));
		internalFrame.setVisible(true);
	}
	
	/**
	 * For displaying internal frame when transitionoing to CALL_DECISION
	 */
	public void changeInternalFrameCallDecision(final String sourceAddrIP, final byte typeCode, final String[] relays)
	{
		String name = (String)StateManager.INSTANCE.getPeerRowFromIP(sourceAddrIP)[1];
		internalFrame.setTitle(name + " (" + sourceAddrIP + 
			") wants to talk to you!");
		framePanel.removeAll();
		JButton acceptButton = new JButton("Accept");
		acceptButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				StateManager.INSTANCE.acceptCall(sourceAddrIP, typeCode, relays);
			}
		});
		JButton rejectButton = new JButton("Reject");
		rejectButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				StateManager.INSTANCE.rejectCall(sourceAddrIP, typeCode, relays);
			}
		});
		framePanel.add(acceptButton);
		framePanel.add(rejectButton);
		internalFrame.setVisible(true);
	}
	
}
